package barcodelib;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Graphics;

public class BarcodeFactory {
	private static int barWidth = 2;
	private static int barHeight = 100; 
	
	/**
	 * Print EAN-13 type of barcode. Every byte of data represents one bar.
	 * @param text Text that will appear below barcode
	 * @param data Barcode data (0 is white, 1 is black)
	 * @param width Width of bitmap
	 * @param height Height of bitmap
	 * @return
	 */
	public static Bitmap print(String text, byte[] data, int width, int height){
		// Barcode's width calculation
		int barMargin = 7*barWidth; //for the first character
		int totalWidth = data.length * barWidth;
		totalWidth += barMargin;
		
		// Barcode's height calculation
		int shortBarHeight = barHeight;
		int guardBarHeight = shortBarHeight + (6 * barWidth);
		int totalHeight = guardBarHeight + 3; 
		
		// Create bitmap
		int bitmapWidth = width;
		int bitmapHeight = height;
		if(totalWidth > width) bitmapWidth = totalWidth;
		if(totalHeight > height) bitmapHeight = totalHeight;
		Bitmap barcode = new Bitmap(bitmapWidth,bitmapHeight);
		Graphics g = Graphics.create(barcode);
		
		// Calculate starting point of drawing 
		int currentX = (bitmapWidth - totalWidth) / 2 + barMargin;
		int currentY = (bitmapHeight - totalHeight) / 2;
		
		// Calculate starting point of each type of bar
		int startBar = 3;
		int middleBar = startBar + 7*6;
		int endBar = middleBar + 5 + 7*6;

		//Draw bars
		for(int i=0; i<data.length; i++){
			if(data[i]==0) g.setColor(Color.WHITE);
			else g.setColor(Color.BLACK);
			
			if(i<3 || (i>=middleBar && i<middleBar+5) || i>=endBar){
				g.fillRect(currentX, currentY, barWidth, guardBarHeight);
			}
			else{
				g.fillRect(currentX, currentY, barWidth, shortBarHeight);
			}
			
			currentX += barWidth;
		}
		
		//Draw first character
		currentX = (bitmapWidth - totalWidth) / 2;
		g.drawText(text.substring(0,1), currentX+2, currentY+shortBarHeight+1);
		
		//Draw left side
		currentX += 7 * barWidth + 3 * barWidth;
		for(int i=1;i<7;i++){
			g.drawText(text.substring(i,i+1), currentX+2, currentY+shortBarHeight+1);
			currentX += (7*barWidth);
		}
		
		//Draw right side
		currentX += (5*barWidth); //middle guard length
		for(int i=7;i<13;i++){
			g.drawText(text.substring(i,i+1), currentX+2, currentY+shortBarHeight+1);
			currentX += (7*barWidth);
		}
		
		return barcode;
	}
	
	/**
	 * Calculate checksum number for input. For more information, visit <a href='http://www.morovia.com/education/utility/upc-ean.asp'>here</a>
	 * @param code Code to be calculated
	 * @return Checksum value
	 */
	public static int calculateCheksum(String code){
		int odd = 0;
		int even = 0;
		
		for(int i=0; i<code.length(); i++){
			if(i%2==0) even += Integer.parseInt(code.substring(i, i+1));
			else odd += Integer.parseInt(code.substring(i, i+1));
		}
		
		odd *= 3;
		int total = odd + even;
		int rem = total % 10;
		
		if(rem==0) return rem;
		else return 10 - rem;
	}
}
